home *** CD-ROM | disk | FTP | other *** search
/ Beginning Mac Programming / Beginning Mac Programming.bin / pc / Open Me for REALbasic 3 / REALbasic 3.2 / Goodies / 3rd Party Demos / 3rd Party Plugins / Misc / PEVocoder 1.0 (PPC) / PEVocodePlugin Source Code / extended.cp < prev    next >
Encoding:
Text File  |  1998-09-12  |  5.4 KB  |  180 lines

  1. /* $Id: extended.c,v 1.2 1998/09/13 00:21:18 emanuel Exp $ */
  2.  
  3. #include <math.h>
  4. #include "extended.h"
  5.  
  6. /*
  7.  * C O N V E R T   T O   I E E E   E X T E N D E D
  8.  */
  9.  
  10. /* Copyright (C) 1988-1991 Apple Computer, Inc.
  11.  * All rights reserved.
  12.  *
  13.  * Machine-independent I/O routines for IEEE floating-point numbers.
  14.  *
  15.  * NaN's and infinities are converted to HUGE_VAL or HUGE, which
  16.  * happens to be infinity on IEEE machines.  Unfortunately, it is
  17.  * impossible to preserve NaN's in a machine-independent way.
  18.  * Infinities are, however, preserved on IEEE machines.
  19.  *
  20.  * These routines have been tested on the following machines:
  21.  *    Apple Macintosh, MPW 3.1 C compiler
  22.  *    Apple Macintosh, THINK C compiler
  23.  *    Silicon Graphics IRIS, MIPS compiler
  24.  *    Cray X/MP and Y/MP
  25.  *    Digital Equipment VAX
  26.  *
  27.  *
  28.  * Implemented by Malcolm Slaney and Ken Turkowski.
  29.  *
  30.  * Malcolm Slaney contributions during 1988-1990 include big- and little-
  31.  * endian file I/O, conversion to and from Motorola's extended 80-bit
  32.  * floating-point format, and conversions to and from IEEE single-
  33.  * precision floating-point format.
  34.  *
  35.  * In 1991, Ken Turkowski implemented the conversions to and from
  36.  * IEEE double-precision format, added more precision to the extended
  37.  * conversions, and accommodated conversions involving +/- infinity,
  38.  * NaN's, and denormalized numbers.
  39.  */
  40.  
  41. #ifndef HUGE_VAL
  42. # define HUGE_VAL HUGE
  43. #endif /*HUGE_VAL*/
  44.  
  45. # define FloatToUnsigned(f)      ((unsigned long)(((long)(f - 2147483648.0)) + 2147483647L) + 1)
  46.  
  47. void ConvertToIeeeExtended(double num, unsigned char *bytes)
  48. {
  49.     int    sign;
  50.     int expon;
  51.     double fMant, fsMant;
  52.     unsigned long hiMant, loMant;
  53.  
  54.     if (num < 0) {
  55.         sign = 0x8000;
  56.         num *= -1;
  57.     } else {
  58.         sign = 0;
  59.     }
  60.  
  61.     if (num == 0) {
  62.         expon = 0; hiMant = 0; loMant = 0;
  63.     }
  64.     else {
  65.         fMant = frexp(num, &expon);
  66.         if ((expon > 16384) || !(fMant < 1)) {    /* Infinity or NaN */
  67.             expon = sign|0x7FFF; hiMant = 0; loMant = 0; /* infinity */
  68.         }
  69.         else {    /* Finite */
  70.             expon += 16382;
  71.             if (expon < 0) {    /* denormalized */
  72.                 fMant = ldexp(fMant, expon);
  73.                 expon = 0;
  74.             }
  75.             expon |= sign;
  76.             fMant = ldexp(fMant, 32);          
  77.             fsMant = floor(fMant); 
  78.             hiMant = FloatToUnsigned(fsMant);
  79.             fMant = ldexp(fMant - fsMant, 32); 
  80.             fsMant = floor(fMant); 
  81.             loMant = FloatToUnsigned(fsMant);
  82.         }
  83.     }
  84.     
  85.     bytes[0] = expon >> 8;
  86.     bytes[1] = expon;
  87.     bytes[2] = hiMant >> 24;
  88.     bytes[3] = hiMant >> 16;
  89.     bytes[4] = hiMant >> 8;
  90.     bytes[5] = hiMant;
  91.     bytes[6] = loMant >> 24;
  92.     bytes[7] = loMant >> 16;
  93.     bytes[8] = loMant >> 8;
  94.     bytes[9] = loMant;
  95. }
  96.  
  97.  
  98. /*
  99.  * C O N V E R T   F R O M   I E E E   E X T E N D E D  
  100.  */
  101.  
  102. /* 
  103.  * Copyright (C) 1988-1991 Apple Computer, Inc.
  104.  * All rights reserved.
  105.  *
  106.  * Machine-independent I/O routines for IEEE floating-point numbers.
  107.  *
  108.  * NaN's and infinities are converted to HUGE_VAL or HUGE, which
  109.  * happens to be infinity on IEEE machines.  Unfortunately, it is
  110.  * impossible to preserve NaN's in a machine-independent way.
  111.  * Infinities are, however, preserved on IEEE machines.
  112.  *
  113.  * These routines have been tested on the following machines:
  114.  *    Apple Macintosh, MPW 3.1 C compiler
  115.  *    Apple Macintosh, THINK C compiler
  116.  *    Silicon Graphics IRIS, MIPS compiler
  117.  *    Cray X/MP and Y/MP
  118.  *    Digital Equipment VAX
  119.  *
  120.  *
  121.  * Implemented by Malcolm Slaney and Ken Turkowski.
  122.  *
  123.  * Malcolm Slaney contributions during 1988-1990 include big- and little-
  124.  * endian file I/O, conversion to and from Motorola's extended 80-bit
  125.  * floating-point format, and conversions to and from IEEE single-
  126.  * precision floating-point format.
  127.  *
  128.  * In 1991, Ken Turkowski implemented the conversions to and from
  129.  * IEEE double-precision format, added more precision to the extended
  130.  * conversions, and accommodated conversions involving +/- infinity,
  131.  * NaN's, and denormalized numbers.
  132.  */
  133.  
  134. #ifndef HUGE_VAL
  135. # define HUGE_VAL HUGE
  136. #endif /*HUGE_VAL*/
  137.  
  138. # define UnsignedToFloat(u)         (((double)((long)(u - 2147483647L - 1))) + 2147483648.0)
  139.  
  140. /****************************************************************
  141.  * Extended precision IEEE floating-point conversion routine.
  142.  ****************************************************************/
  143.  
  144. double ConvertFromIeeeExtended(unsigned char *bytes)
  145. {
  146.     double    f;
  147.     int    expon;
  148.     unsigned long hiMant, loMant;
  149.     
  150.     expon = ((bytes[0] & 0x7F) << 8) | (bytes[1] & 0xFF);
  151.     hiMant    =    ((unsigned long)(bytes[2] & 0xFF) << 24)
  152.             |    ((unsigned long)(bytes[3] & 0xFF) << 16)
  153.             |    ((unsigned long)(bytes[4] & 0xFF) << 8)
  154.             |    ((unsigned long)(bytes[5] & 0xFF));
  155.     loMant    =    ((unsigned long)(bytes[6] & 0xFF) << 24)
  156.             |    ((unsigned long)(bytes[7] & 0xFF) << 16)
  157.             |    ((unsigned long)(bytes[8] & 0xFF) << 8)
  158.             |    ((unsigned long)(bytes[9] & 0xFF));
  159.  
  160.     if (expon == 0 && hiMant == 0 && loMant == 0) {
  161.         f = 0;
  162.     }
  163.     else {
  164.         if (expon == 0x7FFF) {    /* Infinity or NaN */
  165.             f = HUGE_VAL;
  166.         }
  167.         else {
  168.             expon -= 16383;
  169.             f  = ldexp(UnsignedToFloat(hiMant), expon-=31);
  170.             f += ldexp(UnsignedToFloat(loMant), expon-=32);
  171.         }
  172.     }
  173.  
  174.     if (bytes[0] & 0x80)
  175.         return -f;
  176.     else
  177.         return f;
  178. }
  179.  
  180.